/**
 * Copyright (C) 2025 pony working team
 * SPDX-License-Identifier: MulanPSL-2.0
 */

/* define to prevent recursive inclusion -------------------------------------*/
#ifndef __K_SEM_H__
#define __K_SEM_H__

/* includes (standard library, system) ---------------------------------------*/
#include <stdint.h>
/* includes (other library) --------------------------------------------------*/
/* includes (project) --------------------------------------------------------*/
#include <x_atomic.h>
#include <x_list.h>
#include <x_module.h>
/* includes (local) ----------------------------------------------------------*/
#include "k_obj.h"
#include "k_errno.h"
#include "k_tick.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* defines -------------------------------------------------------------------*/

#define ERRNO_SEM_ILLEGAL_ID        ERRNO_JOIN(MID_SEM, 1)
#define ERRNO_SEM_TIMEOUT           ERRNO_JOIN(MID_SEM, 2)
#define ERRNO_SEM_DELETED           ERRNO_JOIN(MID_SEM, 3)
#define ERRNO_SEM_UNAVAILABLE       ERRNO_JOIN(MID_SEM, 4)
#define ERRNO_SEM_ILLEGAL_OPERATION ERRNO_JOIN(MID_SEM, 5)
#define ERRNO_SEM_OVERFLOW          ERRNO_JOIN(MID_SEM, 6)

/* typedefs ------------------------------------------------------------------*/

typedef struct sem {
    obj_t obj;
    atomic_uint count;
    dlist_t pend_q;
} sem_t, *sem_id;

/* macro ---------------------------------------------------------------------*/
/* inlines -------------------------------------------------------------------*/
/* externs -------------------------------------------------------------------*/

extern int sem_init(sem_t *sem, unsigned int value);
extern sem_id sem_create(unsigned int value);
extern sem_id sem_open(const char *name, int oflag, ...);
extern int sem_destroy(sem_t *sem);
extern int sem_timedwait(sem_t *sem, unsigned int timeout);
extern int sem_wait(sem_t *sem);
extern int sem_trywait(sem_t *sem);
extern int sem_post(sem_t *sem);
extern unsigned int sem_getvalue(sem_t *sem);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __K_SEM_H__ */
